package cn.iocoder.yudao.module.esim.dal.mysql.esasset;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.esim.controller.app.esasset.vo.AppEsAssetActiveReqVO;
import cn.iocoder.yudao.module.esim.dal.dataobject.esasset.EsAssetDO;
import cn.iocoder.yudao.module.esim.enums.esasset.EsAssetActiveStateEnum;
import cn.iocoder.yudao.module.esim.enums.esasset.EsAssetDeviceTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.esim.controller.admin.esasset.vo.*;

/**
 * eSim资产 Mapper
 *
 * @author 超管
 */
@Mapper
public interface EsAssetMapper extends BaseMapperX<EsAssetDO> {

    default PageResult<EsAssetDO> selectPage(EsAssetPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<EsAssetDO>()
                .inIfPresent(EsAssetDO::getActiveState, reqVO.getActiveStateList())
                .eqIfPresent(EsAssetDO::getOrderNo, reqVO.getOrderNo())
                .eqIfPresent(EsAssetDO::getUserId, reqVO.getUserId())
                .eqIfPresent(EsAssetDO::getSpuId, reqVO.getSpuId())
                .eqIfPresent(EsAssetDO::getSkuId, reqVO.getSkuId())
                .eqIfPresent(EsAssetDO::getEsProductId, reqVO.getEsProductId())
                .eqIfPresent(EsAssetDO::getTotalDataSizeInMb, reqVO.getTotalDataSizeInMb())
                .eqIfPresent(EsAssetDO::getUsedDataSizeInMb, reqVO.getUsedDataSizeInMb())
                .betweenIfPresent(EsAssetDO::getStartDate, reqVO.getStartDate())
                .betweenIfPresent(EsAssetDO::getEndDate, reqVO.getEndDate())
                .orderByDesc(EsAssetDO::getId));
    }

    default EsAssetDO getAssetByOrderNo(String orderNo) {
        final EsAssetDO assetDO = selectOne(EsAssetDO::getOrderNo, orderNo);
        return assetDO;
    }

    default EsAssetDO getAssetByUserId(Long userId, String assetId) {
        final EsAssetDO assetDO = selectOne(EsAssetDO::getUserId, userId, EsAssetDO::getId, assetId);
        return assetDO;
    }

    default List<EsAssetDO> listByActiveStatus(Long userId, List<EsAssetActiveStateEnum> activeStateEnumList, Set<String> iccids) {
        return listByActiveStatus(userId, activeStateEnumList, null, iccids);
    }

    default List<EsAssetDO> listByActiveStatus(Long userId, List<EsAssetActiveStateEnum> activeStateEnumList, Integer limitSize, Set<String> iccids) {
        final LambdaQueryWrapper<EsAssetDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(EsAssetDO::getUserId, userId);

        final List<Integer> activeStateList = activeStateEnumList.stream().map(v -> v.getValue()).collect(Collectors.toList());
        wrapper.in(EsAssetDO::getActiveState, activeStateList);
        if (CollUtil.isNotEmpty(iccids)){
            wrapper.in(EsAssetDO::getIccid, iccids);
        }
        if (limitSize != null) {
            wrapper.last("LIMIT " + limitSize);
        }

        return selectList(wrapper);
    }

    default int updateName(Long userId, String assetId, String name) {
        final EsAssetDO assetDO = new EsAssetDO();
        assetDO.setName(name);

        final LambdaUpdateWrapper<EsAssetDO> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(EsAssetDO::getUserId, userId);
        wrapper.eq(EsAssetDO::getId, assetId);
        return update(assetDO, wrapper);
    }

    default int updateInUse(Long userId, String assetId, Boolean inUse) {
        final EsAssetDO assetDO = new EsAssetDO();
        assetDO.setInUse(inUse);

        final LambdaUpdateWrapper<EsAssetDO> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(EsAssetDO::getUserId, userId);
        wrapper.eq(EsAssetDO::getId, assetId);
        return update(assetDO, wrapper);
    }

    default int updateInUseExcludeAssetId(Long userId, String excludeAssetId, Boolean inUse) {
        final EsAssetDO assetDO = new EsAssetDO();
        assetDO.setInUse(inUse);

        final LambdaUpdateWrapper<EsAssetDO> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(EsAssetDO::getUserId, userId);
        wrapper.ne(EsAssetDO::getId, excludeAssetId);
        return update(assetDO, wrapper);
    }

    default int active(Long userId, AppEsAssetActiveReqVO reqVO) {
        final EsAssetDO assetDO = new EsAssetDO();
        assetDO.setActiveState(EsAssetActiveStateEnum.ACTIVATED.getValue());
        assetDO.setActiveDate(LocalDateTime.now());
        assetDO.setDeviceType(EsAssetDeviceTypeEnum.WIFI_DEVICE.getValue());
        assetDO.setDeviceImei(reqVO.getDeviceImei());
        assetDO.setDeviceSn(reqVO.getDeviceSn());
        assetDO.setDeviceName(reqVO.getDeviceName());

        final LambdaUpdateWrapper<EsAssetDO> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(EsAssetDO::getUserId, userId);
        wrapper.eq(EsAssetDO::getId, reqVO.getId());
        return update(assetDO, wrapper);
    }

    default int updateActiveStatus(Long userId, String excludeAssetId,
                                   EsAssetActiveStateEnum from, EsAssetActiveStateEnum to) {
        final EsAssetDO assetDO = new EsAssetDO();
        assetDO.setActiveState(to.getValue());
        if (to == EsAssetActiveStateEnum.ACTIVATED) {
            assetDO.setActiveDate(LocalDateTime.now());
        }

        final LambdaUpdateWrapper<EsAssetDO> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(EsAssetDO::getUserId, userId);
        wrapper.eq(EsAssetDO::getActiveState, from.getValue());
        wrapper.ne(EsAssetDO::getId, excludeAssetId);
        return update(assetDO, wrapper);
    }

}